ELFSER page# 0001 next
2: COMMENT ⊗   VALID 00018 PAGES
3: C REC  PAGE   DESCRIPTION
4: C00001 00001
5: C00003 00002    IFN ELFNUM <SUBTTL ELFSER       PDP-11 SERVICE
6: C00005 00003    10/11 interface definitions
7: C00008 00004    Console control box definitions
8: C00010 00005    SPS41 definitions
9: C00011 00006    Service dispatch table, DDB definitions
10: C00013 00007    System initialization, interrupt code, RELEAS, hung code.
11: C00017 00008    Dump-mode I/O: ELFDOU, ELFDIN
12: C00020 00009    MTAPE UUO calling sequence and dispatch, SETIOS routine.
13: C00023 00010    USETI, USETO, UGETF UUO's
14: C00025 00011    MTAPE's: INTWAI, PEEK
15: C00029 00012    MTAPE FILL
16: C00031 00013    Funny MTAPE functions: EXAMINE, DEPOSIT, REG EXAM, REG DEP, PROGRAM START
17: C00033 00014    Read routines: RDB, RDW
18: C00036 00015    Write routines: WTB, WTW, POKE11
19: C00038 00016    Common subroutines for RDB and WTB: RELIOW, UPDADR
20: C00041 00017    Common routines: WDONE, DOCON
21: C00044 00018            USET,SETCON, DLAY
22: C00046 ENDMK
23: C⊗;
    ELFSER page# 0002 next  prev
25: IFN ELFNUM <SUBTTL ELFSER       PDP-11 SERVICE
26: BEGIN ELFSER - 15 MAY 74 - BO
27: 
28: CBOX←←0         ;Nonzero if the control box exists
29: SPS41←←0        ;SPS exists, but we don't have anything to do with it yet.
30: NEWCNI←←0       ;1 when Rubin installs the BUS INIT CONI bit.
31: 
32: IFNDEF DBG11 <DBG11←←0>         ;Nonzero for debugging in user-IOT mode.
33: 
34: COMMENT⊗        DEVIOS bits
35: 
36: 18 IOIMPM
37: 19 IODERR       Interface detected an error
38: 20 IOBKTL       ADRS ERR from an EXAMINE or DEPOSIT.
39: 
40: 21 IODEND       Interface got NXM
41: 22              Interface couldn't get the bus
42: 23 IOACT
43: 
44: 24              BUS INIT going on (NEWCNI)
45: 25              Bad parity
46: 26              Interface is hung
47: 
48: 27
49: 28              Interface still has the UNIBUS (grab mode)
50: 29              No retry on errors.
51: 
52: 30 IOCON
53: 31 IOWC
54: 
55: 32:35 MODE      Modes 16-17 are legal.
56: 
57: Bit 19 is set by the interrupt routine.
58: 
59: Bits 20:22 and 24:29 are set (from a CONI) at the end of each dump-mode
60: transfer.  All of these bits are for the user's information only - they
61: don't affect the operation of the interface.
62: 
63: 
64: HNGBIT←←1000
65: NOTRY←←100
66: INTREQ←←400000          ;Attention bit in LH(DEVIOS)
    ELFSER page# 0003 next  prev
68: ;10/11 interface definitions
69: 
70: ;CONO bits
71: 
72: SETADR←←400000          ;If 1, set address from bits 19:35.
73:                         ;If 0, the other bits have these meanings:
74: 
75: IRESET←←100000          ;Reset the interface
76: CLRINT←←40000           ;Clear the interrupt conditions
77: IGNPAR←←20000           ;Ignore parity on input
78: STOPIT←←10000           ;Stop data transfers
79: DOIT←←4000              ;Start data transfers
80: WRITE←←2000             ;0 ⊃ read, 1 ⊃ write
81: GRAB←←1000              ;Don't let go of the bus
82: SGNEXT←←400             ;Extend sign of inputs
83: ;       Data packing mode:
84:   ONEWD←←0              ;16 bits right-adjusted in a word
85:   TWOWD←←100            ;16 bits right-adj in each halfword
86:   TWOWDR←←200           ;32 bits right-adjusted
87:   TWOWDL←←300           ;32 bits left-adjusted
88: ;       Bits 30-32 are the PI channel for special interrupts,
89: SCHN←←ELFCHN3
90: ;       33-35 the channel for data transfer interrupts.
91: DCHN←←ELDCHN
92: 
93: ;CONI bits, left half
94: 
95: SPINT←←400000           ;Special interrupt (reason in bits 18-23)
96: ;       Bits 1:17 are the contents of the Unibus address register.
97: 
98: 
99: ;CONI bits, right half
100: 
101: IREQ←←400000            ;The 11 requested an interrupt
102: ;       Errors in the data transfer:
103: ADRERR←←200000          ;ADRS ERR from a console operation
104:                         ;(set by software, not a CONI)
105: NXM11←←100000           ;No response to the address from the bus
106: BUSTO←←40000            ;Couldn't get the bus
107: BINIT←←20000            ;BUS INIT in progress
108: PARBAD←←10000           ;Bad parity
109: ;       Status of current transfer:
110: BUSY←←4000              ;Working on it
111: DONE←←2000              ;This causes a Data Transfer interrupt.
112: ;       Bits 26:35 (from GRAB on) are the same as set in the
113: ;       last CONO.
114: 
115: NTRY←←=10               ;No. of retries for BUSTO or hung interface
    ELFSER page# 0004 next  prev
117: ;Console control box definitions
118: 
119: HCOR←←100000            ;First NXM address in the 11.
120: 
121: IFN CBOX <      These locations are on the Unibus.
122: 
123: DEFINE WADDR(ADR){ADR⊗-1}       ;Translate byte to word address
124: 
125: CREG←←WADDR(777170)     ;Comm register 1
126: IREG←←WADDR(777172)     ;Comm register 2 (causes IREQ when written)
127: SREG←←WADDR(777174)     ;Switches 15:00 (write), data lights (read)
128: FREG←←WADDR(777176)     ;Function register
129: 
130: ;FREG bits:     15:14 (w) switch register 17:16
131: ;               12:11 (w) address display mode
132:                         PPHY←←00000
133:                         KRND←←04000
134:                         KRNI←←10000
135:                         CPHY←←14000
136:                         SUPD←←20000
137:                         SUPI←←24000
138:                         USRD←←30000
139:                         USRI←←34000
140: 
141: ;               5 (w) S-INST/S-CYCLE
142:                         SINST←←00
143:                         SCYCL←←40
144: 
145: ;               4 (w) HALT/ENABLE
146:                         ENABL←←00
147:                         HALT ←←20
148: 
149: ;               3:0 (pw) spring-loaded switches
150:                         LADR ←←01
151:                         EXAM ←←02
152:                         DEP  ←←03
153:                         REXAM←←04
154:                         RDEP ←←05
155:                         START←←06
156:                         CONT ←←07
157:                         INT4 ←←10
158:                         INT5 ←←11
159:                         INT6 ←←12
160:                         INT7 ←←13
161: 
162: ;               Bit 0 (r) ADRS ERR
163:                         ADRERR←←1
164: 
165: PSWD←←WADDR(777776)     ;Program Status word
166: STKLIM←←WADDR(777774)   ;Kernel stack limit
167: 
168: >;IFN CBOX
    ELFSER page# 0005 next  prev
170: ;SPS41 definitions
171: 
172: IFN SPS41 <
173: 
174: MCR0←←WADDR(765000)             ;Bit function if 1 (write):
175: 
176:         EXT←←2          ;IOP external
177:         WBE←←4          ;Enable writes into memories
178:         PMENB←←10       ;Enable writes into program memories
179:         CHNENB←←20      ;Enable channels 1-17
180:         ISINT←←40       ;IS internal
181:         INIT←←1000      ;Initialize all interfaces, halt the IS
182: 
183:         EXTERN←←EXT+WBE+PMENB+CHNENB
184:         INTERN←←WBE+PMENB+CHNENB+ISINT
185: 
186: MCR1←←MCR0 + 1
187: 
188:         COFF←←1         ;Master clock off (stop)
189:         ENAB←←2         ;Enable Unibus access to box memories
190: 
191:         STOP41←←COFF+ENAB
192: 
193: MCR2←←MCR1 + 1
194: 
195:         ONESTP←←1       ;Single step anything in internal mode
196: 
197: MCR3←←MCR2 + 1
198: >;IFN SPS41
    ELFSER page# 0006 next  prev
200: ;Service dispatch table, DDB definitions
201: 
202:         JRST ELFINI             ;Initialization
203:         JRST ELFHNG             ;Hung
204: ELFDSP:
205:         JRST ELFREL             ;Release
206:         POPJ P,                 ;Close
207:         JRST UUOERR             ;Out UUO
208:         JRST UUOERR             ;In UUO
209:         JRST CPOPJ1             ;Enter
210:         JRST CPOPJ1             ;Lookup
211:         JRST ELFDOU             ;Dump-mode output
212:         JRST ELFDIN             ;Dump-mode input
213:         JRST ELFUSO             ;USETO
214:         JRST ELFUSI             ;USETI
215:         JRST ELFGTF             ;UGETF
216:         JRST CPOPJ1             ;RENAME
217:         POPJ P,                 ;Close input
218:         POPJ P,                 ;UTPCLR
219:         JRST ELFMTA             ;MTAPE
220: 
221: ;Locations in the DDB, starting at ELFLOC
222: 
223: DEFINE D(X) {X←LL←←L+1}
224: L←←ELFLOC-ELFDDB
225: 
226: D INTCNI        ;CONI from interrupt routine
227: D USOUT         ;<output CONO>,,<output bus address>
228: D USIN          ;<input CONO>,,<input bus address>
229: D UIOWD         ;User's IOWD, in case of shuffling during BUS INIT wait.
    ELFSER page# 0007 next  prev
231: ;System initialization, interrupt code, RELEAS, hung code.
232: 
233: ;First UUO after INIT will call ELFINI to set the default values of the USET's.
234: 
235: ELFIN0: MOVEM   IOS,DEVIOS(DDB)                 ;Special entry for USET and UGETF.
236: ELFREL:                                         ;RELEAS re-initializes.
237: ELFINI: CONO    D11,IRESET+CLRINT               ;Make sure no interrupts can happen.
238:         MOVE    TAC,[XWD DOIT+SCHN,SETADR]      ;Set up the USET words to the
239:         MOVEM   TAC,USIN(DDB)                   ;default mode.
240:         MOVE    TAC,[XWD WRITE+DOIT+SCHN,SETADR]
241:         MOVEM   TAC,USOUT(DDB)
242:         POPJ    P,
243: 
244: 
245: ELFCLS: CONO    D11,STOPIT+SCHN         ;MTAPE 4 turns off GRAB mode.
246:         CONI    D11,TEM                 ;(used to be CLOSE until JBR
247:         TRZ     TEM,GRAB                ;found a problem with that).
248:         MOVEI   IOS,200
249:         ANDCAB  IOS,DEVIOS(DDB)
250:         JRST    CPOPJ1
251: 
252: IFE DBG11 <
253: ;Special interrupt - error or IREQ
254: 
255: ELFINT:
256:         JSR     ELFSAV                  ;Get some AC's
257:         MOVEI   DDB,ELFDDB
258:         MOVE    DAT,DEVMOD(DDB)
259:         TRNE    DAT,ASSPRG              ;Is the interface INITed?
260:         JRST    ELFIN1
261:         CONO    D11,IRESET+CLRINT       ;No.  Ignore the spurious interrupt,
262:         POPJ    P,                      ;fix it so it won't happen again.
263: 
264: ELFIN1: CONI    D11,INTCNI(DDB)
265:         CONO    D11,CLRINT+SCHN         ;clear the interrupt condition.
266: 
267: IFN CBOX <
268:         MOVE    DAT,INTCNI(DDB)         ;Save the status for the I/O routine.
269:         TRNN    DAT,IREQ                ;Did the 11 request this interrupt?
270:         POPJ    P,                      ;No.  There must be a transfer in progress.
271:                                         ;The I/O routine will notice that BUSY and
272:                                         ;DONE are clear.
273:         MOVSI   IOS,DEVSBB
274:         ANDCA   IOS,DEVIOS(DDB)         ;Clear the I/O active indicator,
275:         TLO     IOS,INTREQ              ;set flag saying this interrupt happened.
276:         LDB     J,PJOBN
277:         TLZE    IOS,IOW                 ;Is the job waiting for this interrupt?
278:         PUSHJ   P,SETIOD                ;Yes.  Let it continue.
279:         MOVEM   IOS,DEVIOS(DDB)
280: >;IFN CBOX
281:         POPJ    P,
282: >;IFE DBG11
283: 
284: ;Hung timeout
285: 
286: IFN CBOX <
287: ELFHNG: CONO    PI,ELFOFF       ;Prevent interference from interrupt routine.
288:         TLZ     IOS,DEVSBB
289:         TLZE    IOS,IOW         ;If the job was waiting for an interrupt,
290:         PUSHJ   P,SETIOD        ;let it run.
291:         MOVEM   IOS,DEVIOS(DDB)
292:         CONO    PI,ELFON
293:         JRST    CPOPJ1
294: >;CBOX
295: IFE CBOX <ELFHNG: POPJ P,>
    ELFSER page# 0008 next  prev
297: ;Dump-mode I/O: ELFDOU, ELFDIN
298: 
299: ELFDOU: TLZE IOS,IOBEG
300:         PUSHJ P,ELFINI
301:         MOVE TAC,USOUT(DDB)
302:         XCTR XR,[MOVE DAT,(UUO)]
303:         PUSHJ P,WTB
304:         JFCL                    ;LET USER INSPECT FAILING STATUS
305:         TLO TEM,SETADR
306:         HLRM TEM,USOUT(DDB)
307:         JRST SETIOS
308: 
309: ELFDIN: TLZE IOS,IOBEG
310:         PUSHJ P,ELFINI
311:         MOVE TAC,USIN(DDB)
312:         XCTR XR,[MOVE DAT,(UUO)]
313:         PUSHJ P,RDB
314:         JFCL
315:         TLO TEM,SETADR
316:         HLRM TEM,USIN(DDB)
317:         JRST SETIOS
    ELFSER page# 0009 next  prev
319: ;MTAPE UUO calling sequence and dispatch, SETIOS routine.
320: 
321: COMMENT⊗        Calling sequence:
322: 
323:         MTAPE CHN,ADR
324:         <error return>
325:         <success return>
326: 
327: ADR:    BYTE (9)CODE,MODE(18)BUSADR
328:         <data>
329: 
330: CODE specifies the function.  MODE and BUSADR work the same way as in USETI.
331: <data> is either the thing to be sent or the result that is read.
332: 
333: 
334: ;Dispatch table
335: 
336: IFE CBOX <MTMIN←←1
337:         MTTBL←.-MTMIN>
338: IFN CBOX <MTMIN←←0
339: MTTBL:  MTP0>
340:         FILL11
341:         PEEK11
342:         POKE11
343:         ELFCLS
344: IFN CBOX <      EXAMI
345:                 DEPOS
346:                 REXAMI
347:                 RDEPOS>
348: MTMAX←←.-MTTBL
349: 
350: ELFMTA: TLZE    IOS,IOBEG
351:         PUSHJ   P,ELFINI
352:         XCTR    XR,[MOVE TAC1,(UUO)]    ;Get the code word,
353:         LDB     TAC,[POINT 9,TAC1,8]    ;Pull out the function code.
354:         IOR     TAC1,[XWD SETADR,SETADR];fix it so SETCON does the right thing.
355: IFN MTMIN <CAIL TAC,MTMIN>
356:         CAILE   TAC,MTMAX
357:         JRST    UUOERR                  ;Out of bounds is an illegal UUO.
358:         PUSHJ   P,@MTTBL(TAC)           ;Do your thing,
359:         CAIA
360:         AOS     (P)
361: 
362: SETIOS: MOVEM   IOS,DEVIOS(DDB)
363:         MOVEI   IOS,0                   ;Set up the resulting IOS bits...
364:         LDB     AC1,[POINT 3,TEM,21]    ;NXM, BUSTO
365:         DPB     AC1,[POINT 3,IOS,22]
366:         TRZ     TEM,DONE
367:         LDB     AC1,[POINT 5,TEM,26]    ;PARBAD, BUSY, GRAB.
368:         DPB     AC1,[POINT 5,IOS,28]
369:         TRNE    TEM,NXM11+BUSTO+PARBAD+BUSY+ADRERR
370:         TRO     IOS,IODERR              ;OR the bad ones into IODERR.
371:         IORB    IOS,DEVIOS(DDB)
372:         POPJ    P,
    ELFSER page# 0010 next  prev
374: ;USETI, USETO, UGETF UUO's
375: 
376: COMMENT⊗
377:         UGETF CHN,ADR
378:         <always returns here>
379: 
380: ADR:    <USETI word>    ;Returns results here in the right format for
381:         <USETO word>    ;a subsequent USET to use.
382: 
383: 
384: ELFGTF: TLZE IOS,IOBEG
385:         PUSHJ P,ELFIN0
386:         MOVE TAC,USIN(DDB)
387:         PUSHJ P,GETF
388:         MOVE TAC,USOUT(DDB)
389: 
390: GETF:   LDB TAC1,[POINT 4,TAC,11]
391:         TLNE TAC,IGNPAR
392:         TRO TAC1,20
393:         MOVS TAC1,TAC1
394:         TLO TAC1,400000
395:         HRR TAC1,TAC
396:         XCTR XW,[MOVEM TAC1,(UUO)]
397:         AOS UUO
398:         POPJ P,
399: 
400: COMMENT⊗
401:         USETI CHN,ADR or USETO CHN,ADR
402:         <always returns here>
403: 
404: ADR:    XWD MODE,BUSADR
405: 
406: If bit 0 of C(ADR) is on, sets the data transfer mode for the corresponding
407: direction of transfer from bits 13:17 (IGNPAR, GRAB, SGNEXT, packing mode).
408: If bit 18 is one, sets the bus address for the next dump-mode transfer from
409: bits 19:35.  This address gets updated at the end of each block transfer
410: to point to the next word after the block.
411: 
412: 
413: ELFUSI: TLZE IOS,IOBEG
414:         PUSHJ P,ELFIN0
415:         MOVE TAC,USIN(DDB)
416:         PUSHJ P,USET
417:         MOVEM TAC,USIN(DDB)
418:         POPJ P,
419: 
420: ELFUSO: TLZE IOS,IOBEG
421:         PUSHJ P,ELFIN0
422:         MOVE TAC,USOUT(DDB)
423:         PUSHJ P,USET
424:         MOVEM TAC,USOUT(DDB)
425:         POPJ P,
    ELFSER page# 0011 next  prev
427: ;MTAPE's: INTWAI, PEEK
428: 
429: ;MTAPE opcode 0: INTWAIT.  If the elf has requested an interrupt,
430: ;do a PEEK CREG.  Otherwise:
431: ;If bits 30:35 of the instruction are 0, direct return with no errors indicated.
432: ;If bits 30:35 = 77, go into IOWQ until the elf interrupts, then PEEK CREG.
433: ;Other bit combinations: set the hung timer to that many seconds, go into
434: ;IOWQ until it interrupts or the time runs out.  If the interrupt happens,
435: ;do a PEEK CREG; if it times out, take the direct return with the HUNG DEVIOS
436: ;bit on.
437: 
438: IFN CBOX <
439: MTP0:   TLZE    IOS,INTREQ      ;Has it interrupted?
440:         JRST    INTIN           ;Yes.  Do the peek.
441:         MOVEI   TEM,0           ;No.  Clear error return bits in case...
442:         TRCN    TAC1,77         ;Does he want to wait?
443:         POPJ    P,              ;No wait.  Just return.
444:         TRCN    TAC1,77         ;He does.  Did he specify infinite time?
445:         TRZ     TAC1,77         ;Yes.  Clear the hung timer.
446:         DPB     TAC1,PDVCNT     ;No.  Set the hung timer.
447:         CONO    PI,ELFOFF       ;Avoid interference...
448:         MOVE    IOS,DEVIOS(DDB) ;make sure the interrupt hasn't happened.
449:         TLZE    IOS,INTREQ
450:         JRST    INTIN0
451:         MOVSI   IOS,DEVSBB      ;OK, we're sure now.
452:         IORM    IOS,DEVIOS(DDB) ;Set the I/O busy indicator,
453:         CONO    PI,ELFON
454:         PUSHJ   P,WSYNC         ;wait until something happens.
455: 
456:         MOVEI   TEM,0           ;We wake up.  Clear the error indications.
457:         MOVE    IOS,DEVIOS(DDB)
458:         TLZE    IOS,INTREQ      ;Did the desired interrupt happen?
459:         JRST    INTIN
460:         TRO     IOS,HNGBIT      ;No.  The hung time ran out.
461:         POPJ    P,
462: 
463: INTIN0: CONO    PI,ELFON
464: INTIN:  HRRI    TAC1,SETADR+CREG;Set up a PEEK CREG.
465:         TLNN    TAC1,TWOWDL
466:         TLO     TAC1,TWOWD      ;Fall into the PEEK routine.
467: >;IFN CBOX
468: 
469: ;Peek at one or two words in the 11's memory.
470: 
471: PEEK11: MOVSI   TAC,DOIT+SCHN           ;Set up the CONO.
472:         PUSHJ   P,SETCON
473:         PUSHJ   P,RDW                   ;Read one word in the specified mode.
474:         POPJ    P,                      ;Error return.
475:         XCTR    XW,[MOVEM DAT, 1(UUO)]  ;Success.  Give it to the user.
476:         JRST    CPOPJ1
    ELFSER page# 0012 next  prev
478: ;MTAPE FILL
479: 
480: ;Fill a block with a constant
481: 
482: FILL11: TLZ TAC1,3                      ;Packing mode 0 (ONEWD)
483:         MOVSI TAC,WRITE+DOIT+SCHN       ;Set up the initial CONO.
484:         PUSHJ P,SETCON
485:         XCTR XR,[MOVE DAT,1(UUO)]       ;LH(DAT)=# of words, RH=thing to fill with.
486:         MOVE AC2,[XWD -NTRY,FILLR]      ;Set up the retry address.
487: FILL0:  HLRZ TAC1,DAT
488:         JUMPE TAC1,CPOPJ1
489: FILL1:  PUSHJ P,DOCON                   ;Start the interface in write mode.
490: FILL2:  CONSO D11,DONE
491:         JSP AC1,WDONE
492:         DATAO D11,DAT                   ;When ready, write the data.
493:         SOJG TAC1,FILL2                 ;Repeat until the block is filled.
494:         JRST WTBE                       ;End just like any write.
495: 
496: FILLR:  AOJ TAC1,                       ;Retry needed.  Back up the count.
497:         MOVS TAC1,TAC1
498:         HRR TAC1,DAT
499:         CAMN DAT,TAC1                   ;Did any data go through successfully?
500:         JRST FILL0
501:         SUB TAC1,DAT                    ;Yes.  Update the count of words
502:         ADD DAT,TAC1                    ;remaining,
503:         MOVN TAC1,TAC1
504:         MOVS TAC1,TAC1
505:         ADD TAC1,TAC                    ;move the bus address up to the one
506:         TRO TAC1,SETADR                 ;that failed.
507:         HRR TAC,TAC1
508:         JRST FILL0
    ELFSER page# 0013 next  prev
510: ;Funny MTAPE functions: EXAMINE, DEPOSIT, REG EXAM, REG DEP, PROGRAM START
511: 
512: IFN CBOX <
513: 
514: EXAMI:  PUSHJ   P,LDADR
515:         POPJ    P,
516:         MOVEI   DAT,HALT+CPHY+EXAM
517: RDIT:   PUSHJ   P,WTW
518:         POPJ    P,
519:         PUSHJ   P,RDLGTS
520:         POPJ    P,
521:         XCTR    XW,[HLREM DAT,1(UUO)]
522:         JRST    CPOPJ1
523: 
524: REXAMI: PUSHJ   P,LRADR
525:         POPJ    P,
526:         MOVEI   DAT,HALT+REXAM
527:         JRST    RDIT
528: 
529: DEPOS:  PUSHJ   P,LDADR
530:         POPJ    P,
531:         MOVEI   DAT,HALT+CPHY+DEP
532: WRTIT:  XCTR    XR,[HRL DAT,1(UUO)]
533:         PUSHJ   P,WTW
534:         POPJ    P,
535: 
536: RDLGTS: MOVE    TAC,[XWD DOIT+SCHN,SETADR+SWREG]
537:         TRZ     TAC1,SETADR
538:         PUSHJ   P,SETCON
539:         PUSHJ   P,RDW
540:         POPJ    P,
541:         TRNN    DAT,1
542:         JRST    CPOPJ1
543:         TRO     TEM,ADRERR
544:         POPJ    P,
545: 
546: RDEPOS: PUSHJ   P,LRADR
547:         POPJ    P,
548:         MOVEI   DAT,HALT+RDEP
549:         JRST    WRTIT
550: 
551: LRADR:  MOVEI   DAT,CPHY+HALT+LADR
552:         DPB     TAC1,[POINT 4,DAT,17]
553:         JRST    ADRLOD
554: 
555: LDADR:  MOVEI   DAT,CPHY+HALT+LADR
556:         DPB     TAC1,[POINT 15,DAT,16]
557:         LDB     TAC,[POINT 2,TAC1,20]
558:         DPB     TAC,[POINT 2,DAT,16]
559: ADRLOD: MOVE    TAC,[XWD WRITE+TWOWD+DOIT+SCHN,SETADR+SWREG]
560:         TLNE    TAC1,20
561:         TLO     TAC,GRAB
562:         JRST    WTW
563: 
564: PSTART: MOVEI   DAT,HALT+START
565:         MOVE    TAC,[XWD WRITE+DOIT+SCHN,SETADR+FREG]
566:         PUSHJ   P,WTW
567:         POPJ    P,
568:         PUSHJ   P,LDADR
569:         POPJ    P,
570:         MOVE    TAC,[XWD WRITE+DOIT+SCHN,SETADR+FREG]
571:         MOVEI   DAT,START
572:         PUSHJ   P,WTW
573:         POPJ    P,
574:         JRST    RDLGTS
575: 
576: >;IFN CBOX
    ELFSER page# 0014 next  prev
578: ;Read routines: RDB, RDW
579: 
580: ;Read a block.  Enter with initial CONO bits in TAC, user IOWD in DAT.
581: ;Skips on success, returns final CONI in TEM whether or not the read succeeded.
582: 
583: RDB:    MOVE AC2,[XWD -NTRY,RDBR]       ;Retry address = RDBR.
584:         ADD DAT,[1,,0]                  ;Bugger the word count by one
585:         PUSHJ P,RELIOW                  ;(the last word takes special handling).
586:         JUMPGE DAT,RDBONE               ;If only one word, don't do BLKO's
587: RDB1:   PUSHJ P,DOCON                   ;Start the operation.
588: RDB2:   CONSO D11,DONE                  ;Loop is CONSO, BLKI, JRST RDB2
589:         JSP AC1,WDONE                   ;as long as no errors happen.
590:         BLKI D11,DAT
591:         JRST RDBE                       ;Exit for last word.
592:         JRST RDB2
593: 
594: RDBR:   PUSHJ P,UPDADR                  ;Retry in middle of block - update
595:         JRST RDB1                       ;starting addresses.
596: 
597: RDBER:  PUSHJ P,UPDADR                  ;Retry on last word -
598: RDBONE: PUSHJ P,DOCON                   ;restart the transfer.
599: RDBE:   HRRI AC2,RDBER                  ;Last word: change retry address.
600:         JSP AC1,WDONE                   ;wait for the read to finish,
601:         CONI D11,TEM                    ;get the resulting status,
602:         CONO D11,SETADR                 ;then set the bus adr to 0.
603:         DATAI D11,1(DAT)                ;Read the data.
604:         JRST CPOPJ1
605: 
606: ;The DATAI makes the interface take another sequential read cycle and hang with
607: ;DONE on waiting for another DATAI.  Thus it stays active, and if GRAB is set
608: ;the bus stays grabbed.  We get the status in before the last DATAI for that
609: ;reason, and set the address to 0 to minimize the chance of errors in the dummy
610: ;cycle.
611: 
612: ;Read one word.  Enter with the CONO bits in TAC.  Returns the word read in DAT.
613: ;Skips on success, returns final CONI in TEM whether or not the read succeeded.
614: 
615: RDW:    MOVE AC2,[XWD -NTRY,.+1]        ;Set up retry address and count.
616:         PUSHJ P,DOCON                   ;Start the read,
617:         JSP AC1,WDONE                   ;wait for it.
618:         CONI D11,TEM                    ;Same kind of terminal messing around
619:         CONO D11,SETADR                 ;as at RDBE, for the same reason.
620:         DATAI D11,DAT
621:         JRST CPOPJ1
    ELFSER page# 0015 next  prev
623: ;Write routines: WTB, WTW, POKE11
624: 
625: ;Write a block.  Same sequence as RDB.
626: 
627: WTB:    MOVE AC2,[XWD -NTRY,WTBR]       ;Retry address = WTBR.
628:         PUSHJ P,RELIOW                  ;Get relocated IOWD.
629: WTB1:   PUSHJ P,DOCON                   ;Start the operation.
630: WTB2:   CONSO D11,DONE                  ;If we're lucky, the loop
631:         JSP AC1,WDONE                   ;takes three instructions
632:         BLKO D11,DAT                    ;(CONSO, BLKO, JRST).
633:         JRST WTBE                       ;Ends like any other write.
634:         JRST WTB2
635: 
636: WTBR:   SUB DAT,[1,,1]                  ;Retry needed - back up the IOWD
637:         PUSHJ P,UPDADR                  ;to the address that failed,
638:         JRST WTB1                       ;update the starting address.
639: 
640: ;Change one or two words (POKE UUO).
641: 
642: POKE11: MOVSI TAC,WRITE+DOIT+SCHN       ;Set up the CONO.
643:         PUSHJ P,SETCON
644:         XCTR XR,[MOVE DAT,1(UUO)]       ;Get the data to poke him with,
645: 
646: ;Write one word.  Enter with CONO in TAC, word to send in DAT.
647: ;Same return convention as WTB.
648: 
649: WTW:    MOVE AC2,[XWD -NTRY,.+1]        ;Retry loc and counter.
650:         PUSHJ P,DOCON                   ;Start the write, then
651:         JSP AC1,WDONE                   ;when the interface is ready,
652:         DATAO D11,DAT                   ;send the data.
653: WTBE:   JSP AC1,WDONE                   ;Wait for it to finish and
654:         CONI D11,TEM                    ;return the resulting CONI.
655:         JRST CPOPJ1
    ELFSER page# 0016 next  prev
657: ;Common subroutines for RDB and WTB: RELIOW, UPDADR
658: 
659: ;Common routine for updating the bus address for RDB and WTB in case of
660: ;a retry in the middle of a block.  This routine will not work if a block
661: ;wraps around core, but that should never happen.
662: 
663: UPDADR: SUB DAT,TAC1                    ;How many words were sent before the error?
664:         JUMPE DAT,UPDAD2                ;None means bypass a lot of screwing around.
665:         HRLI AC2,-NTRY                  ;Otherwise, reset the retry counter.
666:         ADDM DAT,UIOWD(DDB)             ;Update the user's IOWD.
667:         HRRZ AC3,DAT                    ;Now for the Unibus address...
668:         TLNE TAC,TWOWDL                 ;in all modes except 0,
669:         LSH AC3,1                       ;2 PDP-11 words per word.
670:         ADD TAC,AC3
671: UPDAD2: ADD DAT,TAC1                    ;Get back the resultant IOWD.
672:         TLNN TEM,NXM11                  ;If we were asleep from a Unibus INIT,
673:         POPJ P,
674:         SKIPA DAT,UIOWD(DDB)            ;pick up the user's IOWD and relocate it.
675: 
676: ;Relocate a user IOWD in DAT.  Sets up TAC1 and UIOWD(DDB) in case of retry.
677: 
678: RELIOW: MOVEM DAT,UIOWD(DDB)            ;Save the user's IOWD.
679:         MOVEI TAC1,1(DAT)               ;The first location involved...
680:         PUSHJ P,RELOCA                  ;relocate it. (Clobbers AC1)
681:         JRST UADRER                     ;Oops.
682:         TLNN TAC,WRITE
683:         JUMPL TAC1,UADRER               ;Check for write protection.
684:         HRRI DAT,-1(TAC1)               ;Here's the relocated base address.
685:         HLRE TAC1,DAT                   ;Now compute the ending address.
686:         MOVM TAC1,TAC1
687:         ADD TAC1,UIOWD(DDB)             ;User's ending address
688:         TLNN TAC,WRITE                  ;If reading,
689:         ADDI TAC1,1                     ;unbugger the word count.
690:         PUSHJ P,RELOCB                  ;Check that address. (uses ac1)
691:         JRST UADRER
692:         MOVE TAC1,DAT                   ;All happy.  Save the resulting IOWD.
693:         POPJ P,
    ELFSER page# 0017 next  prev
695: ;Common routines: WDONE, DOCON
696: 
697: ;Wait, error check, and retry routine.  Called with JSP AC1,WDONE
698: 
699: WDONE:  CONSZ   D11,DONE                ;If this bit is on,
700:         JRST    (AC1)                   ;everything is happy.
701:         MOVEI   AC3,=10                 ;We're going to delay a little while...
702: WDONE1: CONI    D11,TEM
703:         TRNN    TEM,BUSY                ;Until either BUSY goes off
704:         JRST    WDONE2
705:         SOJG    AC3,WDONE1              ;or the time runs out.
706:         CONO D11,IRESET+CLRINT+STOPIT   ;It ran out.  Unhang the interface
707:         JRST    WDONE4                  ;and retry.
708: 
709: WDONE2: TRNE TEM,DONE                   ;BUSY went off.  If DONE is on, we're OK.
710:         JRST (AC1)                      ;Otherwise, an interrupt happened.
711: IFE DBG11 <MOVE TEM,INTCNI(DDB)>        ;Get the bits that caused the interrupt.
712: IFN CBOX <      TRNE TEM,IREQ           ;If it was requested by the 11,
713:                 JRST (AC2)>             ;we get a free retry.
714:         TRNE TEM,BUSTO
715:         JRST WDONE5
716: IFN NEWCNI <    TRNE TEM,NXM11
717:                 TRNN TEM,BINIT
718:                 CAIA>
719: IFE NEWCNI <    TRNE TEM,NXM11>
720:         TRNE IOS,NOTRY
721: WDONE3: POPJ P,
722:         SOJ AC2,
723:         AOBJP AC2,WDONE3
724:         JRST DLAY
725: 
726: WDONE4: TRNE IOS,NOTRY
727:         POPJ P,
728: WDONE5: SOJ AC2,
729:         AOBJN AC2,1(AC2)
730:         POPJ P,
731: 
732: ;This little routine does the CONO's to start a data transfer.
733: 
734: DOCON:  CONO D11,(TAC)                  ;Set the bus address from RH(TAC),
735:         HLR AC1,TAC
736: IFN DBG11 <TRZ AC1,77>          ;Don't enable PI's if debugging
737:         CONO D11,(AC1)                  ;Start the operation from LH(TAC).
738:         POPJ P,
    ELFSER page# 0018 next  prev
740: ;       USET,SETCON, DLAY
741: 
742: ;Common routine for USET's
743: 
744: USET:   XCTR XR,[MOVE TAC1,(UUO)]       ;Falls into SETCON.
745: 
746: ;Routine to set the CONO and address bits, as for USETI
747: ;TAC contains old combination, TAC1 the changes.
748: 
749: SETCON: JUMPGE TAC1,SETC1
750:         HLRZ AC1,TAC1
751:         DPB AC1,[POINT 4,TAC,11]
752:         TRNE AC1,20
753:         TLO TAC,IGNPAR
754: SETC1:  TRNE TAC1,400000
755:         HRR TAC,TAC1
756:         POPJ P,
757: 
758: ;Delay for one clock tick.  Call with JSP AC2,DLAY.  Clobbers AC1 and AC3.
759: 
760: DLAY:
761: IFN DBG11 <
762:         MOVEI AC3,0
763:         SLEEP AC3,
764: >;IFN DBG11
765: IFE DBG11 <
766:         PUSH P,TAC
767:         PUSH P,TAC1
768:         PUSH P,AC2
769:         PUSH P,TEM
770:         MOVEI TAC,1
771:         PUSHJ P,SLEEPT
772:         POP P,TEM
773:         POP P,AC2
774:         POP P,TAC1
775:         POP P,TAC
776: >;IFE DBG11
777:         JRST (AC2)
778: 
779: BEND ELFSER
780: >;IFN ELFNUM
 EOF: ELFSER end-of-file. cnt=17